﻿using System;
using UnityEngine;

// Token: 0x02000040 RID: 64
public class MirrorCameraScript : MonoBehaviour
{
	// Token: 0x06000176 RID: 374 RVA: 0x0000E84C File Offset: 0x0000CA4C
	private void Start()
	{
		this.mirrorScript = base.GetComponentInParent<MirrorScript>();
		this.cameraObject = base.GetComponent<Camera>();
		if (this.mirrorScript.AddFlareLayer)
		{
			this.cameraObject.gameObject.AddComponent<FlareLayer>();
		}
		this.mirrorRenderer = this.MirrorObject.GetComponent<Renderer>();
		if (Application.isPlaying)
		{
			this.mirrorRenderer.sharedMaterial = this.mirrorRenderer.material;
		}
		this.mirrorMaterial = this.mirrorRenderer.sharedMaterial;
		this.CreateRenderTexture();
	}

	// Token: 0x06000177 RID: 375 RVA: 0x0000E8DC File Offset: 0x0000CADC
	private void CreateRenderTexture()
	{
		if (this.reflectionTexture == null || this.oldReflectionTextureSize != this.mirrorScript.TextureSize)
		{
			if (this.reflectionTexture)
			{
				UnityEngine.Object.DestroyImmediate(this.reflectionTexture);
			}
			this.reflectionTexture = new RenderTexture(this.mirrorScript.TextureSize, this.mirrorScript.TextureSize, 16);
			this.reflectionTexture.filterMode = FilterMode.Bilinear;
			this.reflectionTexture.antiAliasing = 1;
			this.reflectionTexture.name = "MirrorRenderTexture_" + base.GetInstanceID();
			this.reflectionTexture.hideFlags = HideFlags.HideAndDontSave;
			this.reflectionTexture.autoGenerateMips = false;
			this.reflectionTexture.wrapMode = TextureWrapMode.Clamp;
			this.mirrorMaterial.SetTexture("_MainTex", this.reflectionTexture);
			this.oldReflectionTextureSize = this.mirrorScript.TextureSize;
		}
		if (this.cameraObject.targetTexture != this.reflectionTexture)
		{
			this.cameraObject.targetTexture = this.reflectionTexture;
		}
	}

	// Token: 0x06000178 RID: 376 RVA: 0x0000E9FE File Offset: 0x0000CBFE
	private void Update()
	{
		this.CreateRenderTexture();
	}

	// Token: 0x06000179 RID: 377 RVA: 0x0000EA08 File Offset: 0x0000CC08
	private void UpdateCameraProperties(Camera src, Camera dest)
	{
		dest.clearFlags = src.clearFlags;
		dest.backgroundColor = src.backgroundColor;
		if (src.clearFlags == CameraClearFlags.Skybox)
		{
			Skybox component = src.GetComponent<Skybox>();
			Skybox component2 = dest.GetComponent<Skybox>();
			if (!component || !component.material)
			{
				component2.enabled = false;
			}
			else
			{
				component2.enabled = true;
				component2.material = component.material;
			}
		}
		dest.orthographic = src.orthographic;
		dest.orthographicSize = src.orthographicSize;
		if (this.mirrorScript.AspectRatio > 0f)
		{
			dest.aspect = this.mirrorScript.AspectRatio;
		}
		else
		{
			dest.aspect = src.aspect;
		}
		dest.renderingPath = src.renderingPath;
	}

	// Token: 0x0600017A RID: 378 RVA: 0x0000EADC File Offset: 0x0000CCDC
	internal void RenderMirror()
	{
		Camera current;
		if (MirrorCameraScript.renderingMirror || !base.enabled || (current = Camera.current) == null || this.mirrorRenderer == null || this.mirrorMaterial == null || !this.mirrorRenderer.enabled)
		{
			return;
		}
		MirrorCameraScript.renderingMirror = true;
		int pixelLightCount = QualitySettings.pixelLightCount;
		if (QualitySettings.pixelLightCount != this.mirrorScript.MaximumPerPixelLights)
		{
			QualitySettings.pixelLightCount = this.mirrorScript.MaximumPerPixelLights;
		}
		try
		{
			this.UpdateCameraProperties(current, this.cameraObject);
			if (this.mirrorScript.MirrorRecursion)
			{
				this.mirrorMaterial.EnableKeyword("MIRROR_RECURSION");
				this.cameraObject.ResetWorldToCameraMatrix();
				this.cameraObject.ResetProjectionMatrix();
				this.cameraObject.projectionMatrix = this.cameraObject.projectionMatrix * Matrix4x4.Scale(new Vector3(-1f, 1f, 1f));
				this.cameraObject.cullingMask = (-17 & this.mirrorScript.ReflectLayers.value);
				GL.invertCulling = true;
				this.cameraObject.Render();
				GL.invertCulling = false;
			}
			else
			{
				this.mirrorMaterial.DisableKeyword("MIRROR_RECURSION");
				Vector3 position = base.transform.position;
				Vector3 lhs = (!this.mirrorScript.NormalIsForward) ? base.transform.up : base.transform.forward;
				float w = -Vector3.Dot(lhs, position) - this.mirrorScript.ClipPlaneOffset;
				Vector4 vector = new Vector4(lhs.x, lhs.y, lhs.z, w);
				this.CalculateReflectionMatrix(ref vector);
				Vector3 position2 = this.cameraObject.transform.position;
				float farClipPlane = this.cameraObject.farClipPlane;
				Vector3 position3 = this.reflectionMatrix.MultiplyPoint(position2);
				Matrix4x4 worldToCameraMatrix = current.worldToCameraMatrix * this.reflectionMatrix;
				this.cameraObject.worldToCameraMatrix = worldToCameraMatrix;
				Vector4 clipPlane = this.CameraSpacePlane(ref worldToCameraMatrix, ref position, ref lhs, 1f);
				this.cameraObject.projectionMatrix = current.CalculateObliqueMatrix(clipPlane);
				GL.invertCulling = true;
				this.cameraObject.transform.position = position3;
				this.cameraObject.farClipPlane = this.mirrorScript.FarClipPlane;
				this.cameraObject.cullingMask = (-17 & this.mirrorScript.ReflectLayers.value);
				this.cameraObject.Render();
				this.cameraObject.transform.position = position2;
				this.cameraObject.farClipPlane = farClipPlane;
				GL.invertCulling = false;
			}
		}
		finally
		{
			MirrorCameraScript.renderingMirror = false;
			if (QualitySettings.pixelLightCount != pixelLightCount)
			{
				QualitySettings.pixelLightCount = pixelLightCount;
			}
		}
	}

	// Token: 0x0600017B RID: 379 RVA: 0x0000EDD4 File Offset: 0x0000CFD4
	private void OnDisable()
	{
		if (this.reflectionTexture)
		{
			UnityEngine.Object.DestroyImmediate(this.reflectionTexture);
			this.reflectionTexture = null;
		}
	}

	// Token: 0x0600017C RID: 380 RVA: 0x0000EDF8 File Offset: 0x0000CFF8
	private Vector4 CameraSpacePlane(ref Matrix4x4 worldToCameraMatrix, ref Vector3 pos, ref Vector3 normal, float sideSign)
	{
		Vector3 point = pos + normal * this.mirrorScript.ClipPlaneOffset;
		Vector3 lhs = worldToCameraMatrix.MultiplyPoint(point);
		Vector3 rhs = worldToCameraMatrix.MultiplyVector(normal).normalized * sideSign;
		return new Vector4(rhs.x, rhs.y, rhs.z, -Vector3.Dot(lhs, rhs));
	}

	// Token: 0x0600017D RID: 381 RVA: 0x0000EE70 File Offset: 0x0000D070
	private void CalculateReflectionMatrix(ref Vector4 plane)
	{
		this.reflectionMatrix.m00 = 1f - 2f * plane[0] * plane[0];
		this.reflectionMatrix.m01 = -2f * plane[0] * plane[1];
		this.reflectionMatrix.m02 = -2f * plane[0] * plane[2];
		this.reflectionMatrix.m03 = -2f * plane[3] * plane[0];
		this.reflectionMatrix.m10 = -2f * plane[1] * plane[0];
		this.reflectionMatrix.m11 = 1f - 2f * plane[1] * plane[1];
		this.reflectionMatrix.m12 = -2f * plane[1] * plane[2];
		this.reflectionMatrix.m13 = -2f * plane[3] * plane[1];
		this.reflectionMatrix.m20 = -2f * plane[2] * plane[0];
		this.reflectionMatrix.m21 = -2f * plane[2] * plane[1];
		this.reflectionMatrix.m22 = 1f - 2f * plane[2] * plane[2];
		this.reflectionMatrix.m23 = -2f * plane[3] * plane[2];
		this.reflectionMatrix.m30 = 0f;
		this.reflectionMatrix.m31 = 0f;
		this.reflectionMatrix.m32 = 0f;
		this.reflectionMatrix.m33 = 1f;
	}

	// Token: 0x0600017E RID: 382 RVA: 0x0000F050 File Offset: 0x0000D250
	private static void CalculateObliqueMatrix(ref Matrix4x4 projection, ref Vector4 clipPlane)
	{
		Vector4 b = projection.inverse * new Vector4(MirrorCameraScript.Sign(clipPlane.x), MirrorCameraScript.Sign(clipPlane.y), 1f, 1f);
		Vector4 vector = clipPlane * (2f / Vector4.Dot(clipPlane, b));
		projection[2] = vector.x - projection[3];
		projection[6] = vector.y - projection[7];
		projection[10] = vector.z - projection[11];
		projection[14] = vector.w - projection[15];
	}

	// Token: 0x0600017F RID: 383 RVA: 0x00002687 File Offset: 0x00000887
	private static float Sign(float a)
	{
		if (a > 0f)
		{
			return 1f;
		}
		if (a < 0f)
		{
			return -1f;
		}
		return 0f;
	}

	// Token: 0x04000259 RID: 601
	public GameObject MirrorObject;

	// Token: 0x0400025A RID: 602
	private Renderer mirrorRenderer;

	// Token: 0x0400025B RID: 603
	private Material mirrorMaterial;

	// Token: 0x0400025C RID: 604
	private MirrorScript mirrorScript;

	// Token: 0x0400025D RID: 605
	private Camera cameraObject;

	// Token: 0x0400025E RID: 606
	private RenderTexture reflectionTexture;

	// Token: 0x0400025F RID: 607
	private Matrix4x4 reflectionMatrix;

	// Token: 0x04000260 RID: 608
	private int oldReflectionTextureSize;

	// Token: 0x04000261 RID: 609
	private static bool renderingMirror;
}
